元件之所以很強大是他還有個資料傳遞功能,讓各個元件互相溝通,今天就要來研究他到底要怎麼傳資料!
在元件上用v-bind將props的資料傳遞進來。
Day08有提及關於命名的方式,props用法也一樣,HTML模板呼叫時要改用連字號寫法,
parentMsg
在模板中轉換為parent-msg
在沒有v-bind綁定的時候,template
中的{{ parentMsg }}
就只會顯示「msg」而已,以純文字的形式呈現(即便裡面是數字也是string
)
<my-component parent-msg="msg"></my-component>
屬性有以下(寫在type裡面時字首大寫)
props:{
'props-num':{
type: Number,
}
},
也可以指定多種格式
props:{
'item':{
type: [Number,String]
}
},
加上default
屬性就可以設定預設值,可以是陣列、物件或是字串。
props:{
'item':{
type: [Number,String],
default:'Hello'
}
},
若以上驗證都不符合需求,可以自己創一個validator
來驗證。
props:{
'item':{
type: Number,
validator: value => value > 0
}
},
這邊將程式分區塊放在一起來理解。
實做之後發現當input內的質改變時,外層物件也被更改了,元件之間相互汙染,為了避免這樣的問題應該先將物件屬性弄成原始型別後再傳資料出去,類似建立副本的概念,這樣就不會汙染其它元件了。
<my-component
v-for="student in students"
:name="student.name"
:age="student.age"
:gender="student.gender">
</my-component>
//簡化
<my-component
v-for="student in students"
:="student">
</my-component>
app.component('my-component', {
template: `
<div class="info-card">
<label>name:<input type="text" v-model="name"></label>
<label>age:<input type="text" v-model="age"></label>
<label>gender:<input type="text" v-model="gender"></label>
</div>
`,
props: ['name', 'age', 'gender']
})
看到現在覺得非常混亂,所以做了一張圖讓兩種寫法做比較,使用原始型別方式才不會改道記憶體中的資料。
JavaScript 引擎會將原始型別強制轉型為 對應的物件型別 : 舉例來說,var a = 1 中,你可以改變變數 a 的內容,但你沒有任何手段可以把儲存 1 這個值的記憶體位置寫入其他內容。更多詳細的內容將在之後介紹 JavaScript傳值還是傳址時討論。—-JavaScript - 原始型別概述
就元件最佳的方式應該是不會汙染父層的單向資料流,所以應該在元件裡面也做一個專屬於仔元件的data
。
app.component('my-component', {
props: ['name', 'age', 'gender'],
data() {
return {
componentName: this.name,
componentAge: this.age,
componentGem: this.gender
}
},
template: `
<div class="info-card">
<label>name:<input type="text" v-model="componentName"></label>
<label>age:<input type="text" v-model="componentAge"></label>
<label>gender:<input type="text" v-model="componentGem"></label>
</div>
`
})